﻿using System;
using System.Collections.Generic;
using System.Linq;
using Tools.Domain.Common.Repositories.Contracts;
using Web.App.Infrastructure.ApplicationMessages.Contracts;
using Web.App.Infrastructure.ApplicationMessages.Implementation;
using Web.App.Infrastructure.Security.Contracts;
using Webshop20.Domain.Common.Exceptions;
using Webshop20.Domain.Customers.Core;
using Webshop20.Domain.Customers.Services.Contracts;

namespace Webshop20.Domain.Customers.Services.Implementation
{
    public class CustomerApprovalService : ICustomerApprovalService
    {
        private const string PATTERN_FOR_REGISTRATION_KEY = "{0}*{1}*{2}";

        private IRepository<Customer> customerRepository;
        private IEncryptionService encryptionService;

        public CustomerApprovalService(IRepository<Customer> customerRepository, IEncryptionService encryptionService)
        {
            this.customerRepository = customerRepository;
            this.encryptionService = encryptionService;
        }

        public void ChangeApprovedCustomersToActiveState(string registrationKey)
        {


            if (string.IsNullOrEmpty(registrationKey))
            {
                throw new DomainException(new FailureMessage(
                             new List<IFailure>
                                 {
                                     new Failure(registrationKey, "NO_REGISTRATION_KEY", "No registration key",
                                                 string.Empty)
                                 },
                             "Customer", "ChangeStateFromPendingToActive", "NO_REGISTRATION_KEY")
                    );
                
            }

            var customerToBeApproved =
                customerRepository.Find(customer => customer.EMail == GetEMailAdressFrom(registrationKey)).FirstOrDefault();

            if(customerToBeApproved == null || !IsValid(registrationKey, customerToBeApproved))
            {
                throw new DomainException(new FailureMessage(
                             new List<IFailure>
                                 {
                                     new Failure(registrationKey, "INVALID_REGISTRATION_KEY", "Invalid registration key",
                                                 string.Empty)
                                 },
                             "Customer", "ChangeStateFromPendingToActive", "INVALID_REGISTRATION_KEY")
                    );
                return;
            }

            customerToBeApproved.ChangeStateTo(CustomerState.active);
            customerToBeApproved.RegisteredAt(DateTime.Now);

        }

        private bool IsValid(string key, Customer customer)
        {
            string decryptString = encryptionService.DecryptString(key);
            string pattern = string.Format(PATTERN_FOR_REGISTRATION_KEY, customer.FirstName, customer.LastName, customer.EMail);
            return decryptString == pattern;
            
        }

        private string GetEMailAdressFrom(string registrationKey)
        {
            try
            {
                return GetRegistrationKeyValues(registrationKey);
            }
            catch
            {
                return string.Empty;
            }
        }

        private string GetRegistrationKeyValues(string registrationKey)
        {
            string decryptedText = encryptionService.DecryptString(registrationKey);
            string [] values = decryptedText.Split('*');
            return values[2];
        }
    }
}